package com.xiaobias;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.*;

public class PasswordGenerator {

    private static final String CHARACTERS =
            "abcdefghijklmnopqrstuvwxyz" +
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                    "0123456789" +
                    "!@#$%^&*()-_=+[]{}|;:,.<>?";

    private static final int MAX_LENGTH = 32;
    private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();

    // RabbitMQ 配置
    private static final String QUEUE_NAME = "password_queue";
    private static final String MQ_HOST = "localhost";
    private static final int MQ_PORT = 5672;
    private static final String MQ_USERNAME = "admin";
    private static final String MQ_PASSWORD = "admin";

    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

        // 初始化 RabbitMQ 连接
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(MQ_HOST);
        factory.setPort(MQ_PORT);
        factory.setUsername(MQ_USERNAME);
        factory.setPassword(MQ_PASSWORD);

        Connection connection = null;

        connection = factory.newConnection();

        for (int length = 1; length <= MAX_LENGTH; length++) {
            int segmentSize = CHARACTERS.length() / THREAD_POOL_SIZE;
            for (int i = 0; i < THREAD_POOL_SIZE; i++) {
                int start = i * segmentSize;
                int end = (i == THREAD_POOL_SIZE - 1) ? CHARACTERS.length() : start + segmentSize;
                String segment = CHARACTERS.substring(start, end);

                // 提交任务到线程池
                executor.submit(new PasswordGeneratorTask(length, segment, connection));
            }
        }

        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        connection.close();
    }

    /**
     * 密码生成任务
     */
    private static class PasswordGeneratorTask implements Runnable {
        private final int length;
        private final String segment;
        private final Connection connection;

        public PasswordGeneratorTask(int length, String segment, Connection connection) {
            this.length = length;
            this.segment = segment;
            this.connection = connection;
        }

        @Override
        public void run() {
            try (Channel channel = connection.createChannel()) {
                channel.queueDeclare(QUEUE_NAME, false, false, false, null);
                System.out.println("Generating passwords of length: " + length + " with segment: " + segment);
                generatePasswordsRecursive("", length, segment, channel);
            } catch (IOException | TimeoutException e) {
                e.printStackTrace();
            }
        }

        /**
         * 递归生成密码组合并发送到 RabbitMQ
         */
        private final static Map<String, String> map = new ConcurrentHashMap<>();
        private void generatePasswordsRecursive(String current, int length, String segment, Channel channel) throws IOException {
            if (current.length() == length) {
                if (!map.containsKey(current)) {
                    map.put(current, current);
                } else {
                    System.err.println("有重复的值：" + map.get(current));
                }
                // 发送密码到 RabbitMQ
                channel.basicPublish("", QUEUE_NAME, null, current.getBytes());
                return;
            }

            for (char c : segment.toCharArray()) {
                generatePasswordsRecursive(current + c, length, CHARACTERS, channel);
            }
        }
    }
}